package com.infinitus.activity.util;

import java.io.File;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.nio.file.Paths;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Map;
import java.util.Properties;

import org.hyperic.sigar.Cpu;
import org.hyperic.sigar.CpuInfo;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.FileSystem;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.Mem;
import org.hyperic.sigar.NetInterfaceConfig;
import org.hyperic.sigar.NetInterfaceStat;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

import com.jfinal.kit.PathKit;
/**
 * @create: 2019/1/9
 * @desc:
 */
public class SigarUtils {
    private static Sigar sigar;

    /**
     * 获取sigar实体
     *
     * @return
     */
    public static Sigar getInstance() {
        if (null == sigar) {
            try {
                // 此处只为得到依赖库文件的目录，可根据实际项目自定义
                // System.out.println("=============="+PathKit.getWebRootPath());
                // 发布后调用
//				 String file = Paths.get(PathKit.getWebRootPath(), "files","sigar",".sigar_shellrc").toString();
                // 本地调试用
                String file = "/Users/icuicy/Documents/code/infinitus/nestwebtemplate/src/main/webapp/files/sigar/.sigar_shellrc";
                File classPath = new File(file).getParentFile();
                String path = System.getProperty("java.library.path");
                String sigarLibPath = classPath.getCanonicalPath();
                // 为防止java.library.path重复加，此处判断了一下
                if (!path.contains(sigarLibPath)) {
                    if (isOSWin()) {
                        path += ";" + sigarLibPath;
                    } else {
                        path += ":" + sigarLibPath;
                    }
                    System.setProperty("java.library.path", path);
                }
                sigar = new Sigar();
            } catch (Exception e) {
                return null;
            }
        }
        return sigar;
    }

    public static boolean isOSWin() {// OS 版本判断
        String OS = System.getProperty("os.name").toLowerCase();
        if (OS.indexOf("win") >= 0) {
            return true;
        } else
            return false;
    }


    /**
     *
     * @Title: memory @Description: 生成内存相关的信息字符串 @author add by zhangxh
     * 2017年2月28日 上午9:55:50 @return @throws SigarException @throws
     *
     */
    public static String memory() throws SigarException {
        Sigar sigar = getInstance();
        Mem mem = sigar.getMem();
        StringBuilder content = new StringBuilder();
        content.append( (mem.getTotal() / 1024L / 1024L)).append("|");
        content.append( (mem.getUsed() / 1024L / 1024L)).append("|");
        content.append( (mem.getFree() / 1024L / 1024L)).append("|");
        // 内存总量
        //System.out.println("内存总量:   " + mem.getTotal() / 1024L + "K av");
        // 当前内存使用量
        //System.out.println("当前内存使用量:    " + mem.getUsed() / 1024L + "K used");
        // 当前内存剩余量
        //System.out.println("当前内存剩余量:    " + mem.getFree() / 1024L + "K free");
        //Swap swap = sigar.getSwap();
        // 交换区总量
        //System.out.println("交换区总量:  " + swap.getTotal() / 1024L + "K av");
        // 当前交换区使用量
        //System.out.println("当前交换区使用量:   " + swap.getUsed() / 1024L + "K used");
        // 当前交换区剩余量
        //System.out.println("当前交换区剩余量:   " + swap.getFree() / 1024L + "K free");
        //System.out.println(content);
        return content.toString();

    }

    /**
     *
     * @Title: cpu @Description: 生成cpu相关信息的字符串 @author add by zhangxh 2017年2月28日
     * 上午9:47:10 @return @throws SigarException @throws
     *
     */
    public static String cpu() throws SigarException {
        Sigar sigar = getInstance();
        Cpu cpu = sigar.getCpu();
        CpuPerc perc = sigar.getCpuPerc();
        Double combined = perc.getCombined();
        NumberFormat ddf1= NumberFormat.getNumberInstance();
        ddf1.setMaximumFractionDigits(4);
        combined = Double.valueOf(ddf1.format(combined)) ;
        // System.out.println(combined);
        //System.out.println("整体cpu的占用情况:");
        //System.out.println("获取当前cpu的空闲率: " + CpuPerc.format(perc.getIdle()));//获取当前cpu的空闲率
        // System.out.println("获取当前cpu的占用率: "+perc.getCombined());//获取当前cpu的占用率

        StringBuilder content = new StringBuilder();
        content.append(cpu.getIdle()).append("|");
        content.append(cpu.getIrq()).append("|");
        content.append(cpu.getNice()).append("|");
        content.append(cpu.getSys()).append("|");
        content.append(cpu.getTotal()).append("|");
        content.append(cpu.getUser()).append("|");
        content.append(cpu.getWait()).append("|");
        content.append(combined).append("|");
        return content.toString();
    }


    /**
     *
     * @Title: file @Description: 磁盘IO信息字符串 @author add by asus 2017年2月28日
     * 上午10:30:54 @return @throws Exception @throws
     *
     */
    public static String file() throws Exception {
        Sigar sigar = getInstance();
        StringBuilder content = new StringBuilder();
        Long total = 0L;
        content.append("{\"fileSystem\":[");
        FileSystem fslist[] = sigar.getFileSystemList();
        for (int i = 0; i < fslist.length; i++) {
            FileSystem fs = fslist[i];
            FileSystemUsage usage = null;
            String dirName = fs.getDirName();
            try {
                usage = sigar.getFileSystemUsage(dirName);
                switch (fs.getType()) {
                    case 0: // TYPE_UNKNOWN ：未知
                        break;
                    case 1: // TYPE_NONE
                        break;
                    case 2: // TYPE_LOCAL_DISK : 本地硬盘
                        String devName = fs.getDevName();
                        total += usage.getTotal();
                        content.append("{\"diskCotnent\":[");
                        content.append("{\"devName\":").append("\"" + devName.replace("\\", "") + "\"");
                        content.append("},{\"total\":").append("\"" + usage.getTotal() / 1024L / 1024L).append("GB" + "\"");
                        content.append("},{\"free\":").append("\"" + usage.getFree() / 1024L / 1024L).append("GB" + "\"");
                        content.append("},{\"avail\":").append("\"" + usage.getAvail() / 1024L / 1024L).append("GB" + "\"");
                        content.append("},{\"used\":").append("\"" + usage.getUsed() / 1024L / 1024L).append("GB" + "\"");
                        double usePercent = usage.getUsePercent() * 100D;
                        content.append("},{\"usePercent\":\"").append(usePercent + "%\"");
                        break;
                    case 3:// TYPE_NETWORK ：网络
                        break;
                    case 4:// TYPE_RAM_DISK ：闪存
                        break;
                    case 5:// TYPE_CDROM ：光驱
                        break;
                    case 6:// TYPE_SWAP ：页面交换
                        break;
                }
                content.append("},{\"diskReads\":").append(usage.getDiskReads());
                content.append("},{\"diskWrites\":").append(usage.getDiskWrites());
                content.append("},{\"divide\":").append(getLongDivide(usage.getDiskReads(), usage.getDiskWrites(), 4));
                content.append("}]},");
            } catch (SigarException e) {
                System.out.println("The device is not ready.");
            }

        }
        content.append("]}").append(";").append(total/ 1024L / 1024L);
        String result = content.toString().replaceAll("}]},]}", "}]}]}");
        return result;
    }

    public static Double getLongDivide(Long l1, Long l2, int point) {
        BigDecimal bd1 = new BigDecimal(l1);
        BigDecimal bd2 = new BigDecimal(l2);
        BigDecimal bd3 = bd1.divide(bd2, point, BigDecimal.ROUND_HALF_EVEN); // point为小数点后几位
        return bd3.doubleValue();
    }

    /**
     *
     * @Title: net @Description: 获取网络相关的信息生产字符串 @author add by zhangxh
     * 2017年2月28日 上午10:34:54 @throws Exception @throws
     *
     */
    public static String net() throws Exception {
        Sigar sigar = getInstance();
        StringBuilder content = new StringBuilder();
        content.append("{\"net\":[");
        String ifNames[] = sigar.getNetInterfaceList();
        for (int i = 0; i < ifNames.length; i++) {
            String name = ifNames[i];
            NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name);
            if ("0.0.0.0".equals(ifconfig.getAddress().trim())) {
                continue;
            }
            if ((ifconfig.getFlags() & 1L) <= 0L) {
                continue;
            }
            NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name);
            content.append("{\"netCotnent\":[");
            content.append("{\"name\":").append("\"" + name + "\"");
            content.append("},{\"rxPackets\":").append(ifstat.getRxPackets());
            content.append("},{\"txPackets\":").append(ifstat.getTxPackets());
            content.append("},{\"getRxBytes\":").append(ifstat.getRxBytes());
            content.append("},{\"getTxBytes\":").append(ifstat.getTxBytes());
            content.append("},{\"getTxErrors\":").append(ifstat.getTxErrors());
            content.append("},{\"getRxDropped\":").append(ifstat.getRxDropped());
            content.append("},{\"getTxDropped\":").append(ifstat.getTxDropped());
            content.append("}]},");
        }
        content.append("]}");
        String result = content.toString().replaceAll("}]},]}", "}]}]}");
        return result;
    }

    /**
     *
     * @Title: fileIo
     * @Description: 磁盘IO
     * @author    add   by zhangxh 2017年3月21日 上午10:33:48
     * @return
     * @throws Exception
     * @throws
     *
     */
    public static String fileIo() throws Exception {
        Sigar sigar = getInstance();
        StringBuilder content = new StringBuilder();


        FileSystem fslist[] = sigar.getFileSystemList();
        FileSystem fs = fslist[0];
        String dirName = fs.getDirName();
        try {
            FileSystemUsage starUsage = sigar.getFileSystemUsage(dirName);
            long start = System.currentTimeMillis();

            long diskReadsStart = starUsage.getDiskReadBytes();  // 读取物理磁盘字节数
            long diskWritesStart = starUsage.getDiskWriteBytes();  //获取写入的物理磁盘字节数。
            Thread.sleep(1000);
            long end = System.currentTimeMillis();
            FileSystemUsage endUsage = sigar.getFileSystemUsage(dirName);
            long diskReadsEnd =  endUsage.getDiskReadBytes();
            long diskWritesEnd = endUsage.getDiskWriteBytes();
            long readsbps = (diskReadsEnd - diskReadsStart)*8/(end-start)*1000;
            long writesbps = (diskWritesEnd - diskWritesStart)*8/(end-start)*1000;
            content.append(readsbps/1024).append("|").append(writesbps/1024).append("|");
        } catch (SigarException e) {
            System.out.println("The device is not ready.");
        }
        return content.toString();
    }


    /**
     *
     * @Title: netIo
     * @Description: 网络IO
     * @author    add   by zhangxh 2017年3月21日 上午10:34:17
     * @return
     * @throws Exception
     * @throws
     *
     */
    public static String netIo() throws Exception {
        Sigar sigar = getInstance();
        StringBuilder content = new StringBuilder();
        String ifNames[] = sigar.getNetInterfaceList();
        String name = ifNames[0];
        long start = System.currentTimeMillis();
        NetInterfaceStat statStart = sigar.getNetInterfaceStat(name);
        long rxBytesStart = statStart.getRxBytes();  // 接收的总包裹数
        long txBytesStart = statStart.getTxBytes();  // 发送的总包裹数
        Thread.sleep(1000);
        long end = System.currentTimeMillis();
        NetInterfaceStat statEnd = sigar.getNetInterfaceStat(name);
        long rxBytesEnd = statEnd.getRxBytes();
        long txBytesEnd = statEnd.getTxBytes();
        long rxbps = (rxBytesEnd - rxBytesStart)*8/(end-start)*1000;
        long txbps = (txBytesEnd - txBytesStart)*8/(end-start)*1000;
        content.append(rxbps/1024).append("|").append(txbps/1024).append("|");
        return content.toString();
    }


    public static void main(String args[]) {
        try {
            Runtime r = Runtime.getRuntime();
            Properties props = System.getProperties();
            InetAddress addr;
            addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress();
            Map<String, String> map = System.getenv();
            String userName = map.get("USERNAME");// 获取用户名
            String computerName = map.get("COMPUTERNAME");// 获取计算机名
            String userDomain = map.get("USERDOMAIN");// 获取计算机域名
            StringBuilder info = new StringBuilder();
            Sigar sigar = getInstance();

            info.append("{\"computerName\":").append("\""+computerName+"\"},").append("{\"ip\":")
                    .append("\""+ip+"\"},").append("{\"hostName\":").append("\""+addr.getHostName()+"\"},");
            CpuInfo infos[] = sigar.getCpuInfoList();
            //Cpu cpu = sigar.getCpu();
            Mem mem = sigar.getMem();
            info.append("{\"countCpu\":").append(infos.length).append("},{\"totalMemory\":\"").append(mem.getTotal()/1024L/1024L/1024L).append("GB\"},");
            String fileContent = file();
            String[] fileArr = fileContent.split(";");
            info.append("{\"diskTotal\":\"").append(fileArr[1]).append("GB\"}");
            //System.out.println("info=========================="+info);

            String result = "[{\"currentTime\":" + System.currentTimeMillis() + "}," +info.toString()+","+ cpu() + "," + memory() + ","
                    + net() + "," + fileArr[0] + "]|";

            System.out.println("=========>>>>>>>>>>>>>>>===============" + result);
            Calendar c = Calendar.getInstance();// 可以对每个时间域单独修改
            int date = c.get(Calendar.DATE);

            // String path = Paths.get(PathKit.getWebRootPath(),
            // "logstxt").toString();
            // 本地调试用
            String path = "E:\\al\\nestwebtemplate\\nestwebtemplate\\src\\main\\webapp\\logstxt\\";
            // 删除前一天的
            c.add(Calendar.DATE, -1);// 日期减1
            // 删除前一天的
            int lastDate = c.get(Calendar.DATE);
            File fileLast = new File(path + "ecs" + lastDate + ".txt");
            FileUtils.deleteFile(fileLast);

            String fileName = "ecs" + date + ".txt";
            FileUtils.createFileFolder(path);
            File file = new File(path + fileName);
            FileUtils.writeFile(result, file, true);

        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

}